package cn.tedu.yang;

import javax.swing.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class Yang extends JFrame {      /*创建了一个小窗口*/

    private  JPanel panel =new JPanel();//窗口中的面板
    /**
     * JLabel 是Swing中用于显示文字和图片的控件
     */
    private JLabel background;
    //创建卡牌集合
    private ArrayList<Card> cards = new ArrayList<>();
    /**
     * 利用List集合保存全部的卡牌
     */
    private  ArrayList<Card> though =new ArrayList<>();

    /*使用数组存放全部的名称*/
    private String[] names = {"刷子","剪刀","叉子","奶瓶",
                                "干草","手套","树桩", "棉花",
                                 "毛线","水桶","火","玉米",
                                "白菜","草","萝卜","铃铛"};
    //创建一个定时器用于让消除效果延迟显示
    private Timer timer= new Timer();

    public Yang(){
        setTitle("羊了个羊1.0版本_BXDD"); //设置窗口标题
        setSize(500, 850);//设置窗口大小
        setLocationRelativeTo(null);//设置窗口大小不能被改变
        setDefaultCloseOperation(EXIT_ON_CLOSE); //设置关闭窗口时退出程序
        add(panel); //将内容添加到窗口中
        panel.setLayout(null);  //关闭panel的布局管理器
        //加载图片
        background = new JLabel(new ImageIcon("images/背景.jpg"));

        background.setLocation(0,0);//关闭布局以后，需要自定义元素位置才能显示
        background.setSize(480,800);//设置背景大小
        //显示图片
        panel.add(background); //面板添加显示图片
        init();

    }

    /**
     * 创建全部的卡牌，放到集合cards中
     * @param times 次数，需要3的整数倍  3  6  9等
     */
    private void createCards(int times){
//        times次遍历数组，将数组的内容添加到数组中
        for (int i = 0; i < times; i++) {
            for(String name: names) {
                Card card= new Card(name);
                cards.add(card);
            }
        }
    }

    //利用 Card 简化代码  初始化游戏
    private void init(){
        //card创建简化代码
        createCards(6);
        System.out.println(cards.size());
        printCards(); //打印牌
        //打乱集合   shuffle
        Collections.shuffle(cards);
        printCards(); //再次打印
        //随机洗牌，顺序放牌// 摆放牌到窗口上
        //   x坐标， y坐标， 总数， 行数， 列数
        deal(33,100,0,6,7);   //累积摆放三层牌
        deal(33+30,100+33,6*7,5,6);
        deal(33,100+66,6*7+5*6,4,7);

      /*  deal(33,100+66,6*7+5*6,4,7);
        deal(33,100+33,42+30+28,5,6);*/
        checkCovered(); //调用检查方法
        //添加动作:为每张牌添加点击事件
        addAction();

    }

    /**
     * 为每个卡牌添加鼠标点击事件
     */
    private void addAction(){
        for(Card card :cards){
            //Card从JButton 继承了 鼠标事件方法
            //ActionListener  :功能性接口，可以利用lamdba表达式实现
            card.addActionListener((e)->{
                System.out.println("点击了卡牌");
                //事件来源就是被点击的牌 称为选定的牌对象
               Card selected = (Card) e.getSource();
                System.out.println(selected);
                //使用方法处理点击事件
                cardToThough(selected);
                checkCovered(); //调用检查方法，把应该点亮的牌点亮
            });
        }
    }


    private void cardToThough(Card selected){
        //如果木栏满了以后，弹出提示框，并结束程序
        if (though.size()==7){
            JOptionPane.showMessageDialog(this,"槽子满了");
            return;
        }
            //从原有集合中删除卡牌
            cards.remove(selected);
//            从cards删除的牌去除鼠标点击事件
            selected.removeActionListeners();
          /*  //添加到新集合中，并重新设置在指定位置
            int x = 22 + though.size() * 63;
            selected.setLocation(x, 642);
            though.add(selected);*/
            int  found = -1;
            for (int i = 0 ;i<though.size();i++){
                Card card= though.get(i);//获取到牌，
                if(card.sameAs(selected)){
                    found=i;    //如果找到了一样的，就把i赋给found并退出此次循环
                    break;
                }
            }
            if (found == -1) {
                //如果没有找到，牌就插入到最后
                though.add(selected);
            } else {
                //如果找到了牌，就插入找到的位置
                though.add(found, selected);
            }
            tryRemoveCards(found,selected);
            //重新排列牌的显示位置
            int x = 22;
            for (Card card: though){
                card.setLocation(x, 642);
                x += 63;
            }
            panel.repaint();
            checkCovered();//点亮变化以后最上面的
        }

    /**
     * 消除算法
     * @param found
     * @param selected
     */
    private void tryRemoveCards(int found,Card selected){

                //在最后时候追加时候，不需要删除牌
                if(found==-1){
                    return;
                }
                //当前位置开始。到最后要至少有3张牌
                if (found + 3 <= though.size()) {
                    //检查当前牌和下下张牌是否一样
                    Card nextNextCard = though.get(found + 2);
                    //如果一样找到了连续三张牌
                    if (selected.sameAs(nextNextCard)) {
                        timer.schedule(new TimerTask(){
                            @Override
                            public void run(){
                                //连续删3张牌，集合中删除三张一样的牌
                                Card c1 = though.remove(found);
                                Card c2 = though.remove(found);
                                Card c3 = though.remove(found);
                                //从窗口中删除
                                panel.remove(c1);
                                panel.remove(c2);
                                panel.remove(c3);
                                //并重新排序
                                int x = 22;
                                for (Card card: though){
                                    card.setLocation(x, 642);
                                    x += 63;
                                } //删除后续重新绘制窗口
                                panel.repaint();
                            }
                        },200);//延迟200ms执行
                    }
                }
           }
    /**
     * 检查全部的相互遮挡关系
     */
    private void checkCovered(){
        //检查每个牌，是否被后续牌遮挡，如果遮挡就是disable状态，否则
        for (int i = 0; i < cards.size(); i++) {
            //找到当前牌
            Card card1 =cards.get(i);
            //检查后续牌是否遮挡了这张牌
            card1.setEnabled(true);
            for (int j = i+1; j < cards.size(); j++) {
                Card card2 =cards.get(j);
                //检查后一张牌是否遮盖了card1
                if(card2.covered(card1)){
                    card1.setEnabled(false);
                }
            }
        }
    }

    /**
     * 打印牌
     */
    private void printCards() {
        int i = 1;
        for (Card card : cards) {
            System.out.print(card + " ");
            if (i++ % 7 == 0) {
                System.out.println();
            }
        }
        System.out.println();
    }

    /**
     * 摆放牌，摆放到没有牌就结束
     * @param x 左上角坐标x x=33
     * @param y 左上角坐标y y=100
     * @param start 开始位置，0 ， 42,42+30
     * @param rows 行数，6
     * @param cols 列数，7
     */
    private void deal(int x, int y, int start, int rows, int cols) {
        //循环到固定次数并且还有可以使用的牌
        for (int i = 0; i < rows * cols && (i + start < cards.size()); i++) {
            int x0 = x + i % cols * 59;//初始位置x的改变
            int y0 = y + i / cols * 66;//初始位置y的改变
            Card card = cards.get(i + start); //获取卡牌对象
            card.setLocation(x0, y0);   //给设置卡牌x，y参数
            card.setEnabled(false);  //按钮不用
            panel.add(card, 0);//面板添加
        }
    }
    public static void main(String[] args) {
        Yang yang = new Yang();//创建yang的对象，自动自行构造方法
        yang.setVisible(true);//显示窗口
    }
}
